#include "EventLoopThread.h"
#include "EventLoop.h"

EventLoopThread::EventLoopThread(const ThreadInitCallback &cb, const std::string name)
        : loop_(nullptr),
          exiting_(false),
          thread_(std::bind(&EventLoopThread::threadFunc, this), name),
          mutex_(),
          cond_(),
          callback_(cb)
{

}

EventLoopThread::~EventLoopThread(){
    exiting_ = true;
    if(loop_ != nullptr){   
        loop_->quit();
        thread_.join();   //用于主线程等待子线程执行完毕并回收子线程的资源
    }
}

EventLoop* EventLoopThread::startLoop(){
    //0.一个线程对应一个loop
    //1.创建一个线程，使用封装的Thread类的start函数
    thread_.start();
    //2.创建一个EventLoop对象
    EventLoop *loop;
    //3.将loop_赋值给loop对象，这里loop_必须不为nullptr
    {
        std::unique_lock<std::mutex> lock(mutex_);
        while(loop_ != nullptr){
            cond_.wait(lock); //??参数是lock而不是mutex_
        }
        loop = loop_;
    }
    //4.返回loop
    return loop;
}
    
void EventLoopThread::threadFunc(){
    //1.声明一个局部EventLoop
    EventLoop loop;
    //2.设置回调函数
    if(callback_){         //这里先判断是为了保证callback_已经被正确初始化了。而不是一个nullptr
       callback_(&loop);   //这里为什么要传入loop的地址
    }
    //3.用步骤一的loop给loop_赋值，注意loop_是一个共享变量，所以要使用互斥锁
    {
       std::unique_lock<std::mutex> lock(mutex_); //?? 声明格式
       loop_ = &loop;
       cond_.notify_one();  //？？忘记条件变量
    }
    //4.调用loop的loop函数，其实就是Reactor中的while循环
    loop_->loop();
    //5.回收资源
    std::unique_lock<std::mutex> lock(mutex_);
    loop_ = nullptr;
}